package com.quanshu.exchange.ui.gui.message.chat.expand;

import android.media.AudioManager;
import android.media.RingtoneManager;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.baselibrary.util.glide.GlideUtils;
import com.hyphenate.chat.EMCallStateChangeListener;
import com.hyphenate.chat.EMClient;
import com.hyphenate.exceptions.HyphenateException;
import com.quanshu.exchange.R;
import com.quanshu.exchange.support.api.UserInterface;
import com.quanshu.exchange.support.db.UserDao;
import com.quanshu.exchange.support.entity.UserEntity;
import com.quanshu.exchange.support.net.BaseResponse;
import com.quanshu.exchange.support.net.core.BaseObserver;
import com.quanshu.exchange.support.net.core.NetClient;
import com.quanshu.exchange.support.utils.AppUtils;
import com.quanshu.exchange.support.utils.ToastHelper;
import com.quanshu.exchange.ui.widget.MyChronometer;

import java.util.UUID;

import butterknife.BindView;
import butterknife.ButterKnife;

import static com.quanshu.exchange.support.config.Config.MAKE_CALL_TIMEOUT;

/**
 * Created by jye on 2018/3/5.
 */

public class VoiceCallActivity extends CallActivity {

//    @BindView(R.id.zoom_in_out_btn)
//    ImageView zoomInOutBtn;
    @BindView(R.id.dest_user_avatar)
    ImageView destUserAvatar;
    @BindView(R.id.dest_user_name)
    TextView destUserName;
    @BindView(R.id.voice_call_tip)
    TextView voiceCallTip;
    @BindView(R.id.chronometer)
    MyChronometer chronometer;
    @BindView(R.id.hang_cancel_btn)
    ImageButton hangCancelBtn;
    @BindView(R.id.hang_cancel_layout)
    RelativeLayout hangCancelLayout;
    @BindView(R.id.hang_up_btn)
    ImageButton hangUpBtn;
    @BindView(R.id.hang_up_layout)
    RelativeLayout hangUpLayout;
    @BindView(R.id.hang_mute_btn)
    ImageButton hangMuteBtn;
    @BindView(R.id.hang_mute_layout)
    RelativeLayout hangMuteLayout;
    @BindView(R.id.hang_answer_btn)
    ImageButton hangAnswerBtn;
    @BindView(R.id.hang_answer_layout)
    RelativeLayout hangAnswerLayout;
    @BindView(R.id.hands_free_btn)
    ImageButton handsFreeBtn;
    @BindView(R.id.hands_free_layout)
    RelativeLayout handsFreeLayout;
    @BindView(R.id.hang_cancel_tip)
    TextView hangCancelTip;
    @BindView(R.id.hang_up_tip)
    TextView hangUpTip;

    private UserEntity userEntity;
    private boolean isMuteState;
    private boolean isHandsfreeState;
    private boolean endCallTriggerByMe = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            finish();
            return;
        }
        setContentView(R.layout.activity_chat_voice_call);
        ButterKnife.bind(this);

        callType = 0;
        getWindow().addFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

        initIntent();
        initView();
        initListener();

    }

    private void initIntent() {
        msgid = UUID.randomUUID().toString();
        username = getIntent().getStringExtra("username");
        isInComingCall = getIntent().getBooleanExtra("isComingCall", false);
    }

    private void initView() {
        userEntity = UserDao.getInstance().query(username);
        if (userEntity == null) {
            doSyncFriend();
        }

        // 如果是正在拨打对方语音聊天
        if (!isInComingCall) {

            initOutgoingCallView();
            soundPool = new SoundPool(1, AudioManager.STREAM_RING, 0);
            outgoing = soundPool.load(this, R.raw.outgoing, 1);
            handler.sendEmptyMessage(MSG_CALL_MAKE_VOICE);
            handler.postDelayed(new Runnable() {
                public void run() {
                    streamID = playMakeCallSounds();
                }
            }, 300);

        } else {

            initComingCallView();
            Uri ringUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
            audioManager.setMode(AudioManager.MODE_RINGTONE);
            audioManager.setSpeakerphoneOn(true);
            ringtone = RingtoneManager.getRingtone(this, ringUri);
            ringtone.play();
            handler.removeCallbacks(timeoutHangup);
            handler.postDelayed(timeoutHangup, MAKE_CALL_TIMEOUT);
        }
    }

    private void initListener() {

        addCallStateListener();

        hangAnswerBtn.setOnClickListener(view -> doClickHangAnswerBtn());

        hangCancelBtn.setOnClickListener(view -> doClickHangCancelBtn());

        hangMuteBtn.setOnClickListener(view -> doClickHangMuteBtn());

        hangUpBtn.setOnClickListener(view -> doClickHangUpBtn());

        handsFreeBtn.setOnClickListener(view -> doClickHandsFreeBtn());

    }

    private void onCallConnecting() {
        runOnUiThread(() -> voiceCallTip.setText(R.string.Are_connected_to_each_other));

    }

    private void onCallConnected() {
//        runOnUiThread(() -> voiceCallTip.setVisibility(View.GONE));

    }

    private void onCallAccepted() {

        handler.removeCallbacks(timeoutHangup);
        runOnUiThread(() -> {
            try {
                if (soundPool != null)
                    soundPool.stop(streamID);
            } catch (Exception e) {
            }
            if (!isHandsfreeState)
                closeSpeakerOn();
            chronometer.setVisibility(View.VISIBLE);
            chronometer.setBase(SystemClock.elapsedRealtime());
            // duration start
            chronometer.start();
            callingState = CallingState.NORMAL;
            voiceCallTip.setVisibility(View.GONE);
            handsFreeLayout.setVisibility(View.VISIBLE);
            hangCancelLayout.setVisibility(View.VISIBLE);
            hangUpLayout.setVisibility(View.GONE);
            hangMuteLayout.setVisibility(View.VISIBLE);
            hangAnswerLayout.setVisibility(View.GONE);

        });
    }

    private void onCallNetWorkUnstable(final EMCallStateChangeListener.CallError error) {

        runOnUiThread(() -> {
            voiceCallTip.setVisibility(View.VISIBLE);
            if (error == EMCallStateChangeListener.CallError.ERROR_NO_DATA) {
                voiceCallTip.setText(R.string.no_call_data);
            } else {
                voiceCallTip.setText(R.string.network_unstable);
            }
        });
    }

    private void onCallNetWorkNormal() {
//        runOnUiThread(() -> voiceCallTip.setVisibility(View.GONE));
    }

    void removeCallStateListener() {
        EMClient.getInstance().callManager().removeCallStateChangeListener(callStateListener);
    }

    private void onCallDisConnected(final EMCallStateChangeListener.CallError error) {

        handler.removeCallbacks(timeoutHangup);
        @SuppressWarnings("UnnecessaryLocalVariable") final EMCallStateChangeListener.CallError fError = error;
        runOnUiThread(new Runnable() {
            private void postDelayedCloseMsg() {
                handler.postDelayed(() -> runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        removeCallStateListener();
                        saveCallRecord();
                        Animation animation = new AlphaAnimation(1.0f, 0.0f);
                        animation.setDuration(800);
                        finish();
                    }
                }), 200);
            }

            @Override
            public void run() {
                chronometer.stop();
                callDruationText = chronometer.getText().toString();
                String st1 = getResources().getString(R.string.Refused);
                String st2 = getResources().getString(R.string.The_other_party_refused_to_accept);
                String st3 = getResources().getString(R.string.Connection_failure);
                String st4 = getResources().getString(R.string.The_other_party_is_not_online);
                String st5 = getResources().getString(R.string.The_other_is_on_the_phone_please);

                String st6 = getResources().getString(R.string.The_other_party_did_not_answer_new);
                String st7 = getResources().getString(R.string.hang_up);
                String st8 = getResources().getString(R.string.The_other_is_hang_up);

                String st9 = getResources().getString(R.string.did_not_answer);
                String st10 = getResources().getString(R.string.Has_been_cancelled);
                String st11 = getResources().getString(R.string.hang_up);

                if (fError == EMCallStateChangeListener.CallError.REJECTED) {
                    callingState = CallingState.BEREFUSED;
                    ToastHelper.toast(st2);
                } else if (fError == EMCallStateChangeListener.CallError.ERROR_TRANSPORT) {
                    ToastHelper.toast(st3);
                } else if (fError == EMCallStateChangeListener.CallError.ERROR_UNAVAILABLE) {
                    callingState = CallingState.OFFLINE;
                    ToastHelper.toast(st4);
                } else if (fError == EMCallStateChangeListener.CallError.ERROR_BUSY) {
                    callingState = CallingState.BUSY;
                    ToastHelper.toast(st5);
                } else if (fError == EMCallStateChangeListener.CallError.ERROR_NORESPONSE) {
                    callingState = CallingState.NO_RESPONSE;
                    ToastHelper.toast(st6);
                } else if (fError == EMCallStateChangeListener.CallError.ERROR_LOCAL_SDK_VERSION_OUTDATED || fError == EMCallStateChangeListener.CallError.ERROR_REMOTE_SDK_VERSION_OUTDATED) {
                    callingState = CallingState.VERSION_NOT_SAME;
                    ToastHelper.toast("通话协议版本不一致");
                } else {
                    if (isRefused) {
                        callingState = CallingState.REFUSED;
                        voiceCallTip.setVisibility(View.VISIBLE);
                        voiceCallTip.setText(st1);
                    } else if (isAnswered) {
                        callingState = CallingState.NORMAL;
                        if (endCallTriggerByMe) {
//                                        callStateTextView.setText(st7);
                        } else {
                            voiceCallTip.setText(st8);
                            voiceCallTip.setVisibility(View.VISIBLE);
                        }
                    } else {
                        if (isInComingCall) {
                            callingState = CallingState.UNANSWERED;
                            voiceCallTip.setVisibility(View.VISIBLE);
                            voiceCallTip.setText(st9);
                        } else {
                            if (callingState != CallingState.NORMAL) {
                                callingState = CallingState.CANCELLED;
                                voiceCallTip.setVisibility(View.VISIBLE);
                                voiceCallTip.setText(st10);
                            } else {
                                voiceCallTip.setVisibility(View.VISIBLE);
                                voiceCallTip.setText(st11);
                            }
                        }
                    }
                }
                postDelayedCloseMsg();
            }

        });

    }

    private void addCallStateListener() {

        callStateListener = (callState, error) -> {
            // Message msg = handler.obtainMessage();
            switch (callState) {

                case CONNECTING:
                    onCallConnecting();
                    break;
                case CONNECTED:
                    onCallConnected();
                    break;
                case ACCEPTED:
                    onCallAccepted();
                    break;
                case NETWORK_UNSTABLE:
                    onCallNetWorkUnstable(error);
                    break;
                case NETWORK_NORMAL:
                    onCallNetWorkNormal();
                    break;
                case VOICE_PAUSE:
                    break;
                case VOICE_RESUME:
                    break;
                case DISCONNECTED:
                    onCallDisConnected(error);
                    break;

                default:
                    break;
            }

        };
        EMClient.getInstance().callManager().addCallStateChangeListener(callStateListener);

    }

    private void doClickHandsFreeBtn() {
        if (isHandsfreeState) {
            handsFreeBtn.setBackgroundResource(R.drawable.icon_hands_free);
            closeSpeakerOn();
            isHandsfreeState = false;
        } else {
            handsFreeBtn.setBackgroundResource(R.drawable.icon_hands_free_open);
            openSpeakerOn();
            isHandsfreeState = true;
        }
    }

    private void doClickHangUpBtn() {

        if (hangUpTip.getText().toString().equals("拒绝")) {
            isRefused = true;
            hangUpBtn.setEnabled(false);
            handler.sendEmptyMessage(MSG_CALL_REJECT);
        } else {
            hangUpBtn.setEnabled(false);
            chronometer.stop();
            endCallTriggerByMe = true;
            handler.sendEmptyMessage(MSG_CALL_END);
        }
    }

    private void doClickHangMuteBtn() {
        if (isMuteState) {
            hangMuteBtn.setBackgroundResource(R.drawable.icon_mute);
            try {
                EMClient.getInstance().callManager().resumeVoiceTransfer();
            } catch (HyphenateException e) {
                e.printStackTrace();
            }
            isMuteState = false;
        } else {
            hangMuteBtn.setBackgroundResource(R.drawable.icon_mute_open);
            try {
                EMClient.getInstance().callManager().pauseVoiceTransfer();
            } catch (HyphenateException e) {
                e.printStackTrace();
            }
            isMuteState = true;
        }
    }

    private void doClickHangCancelBtn() {
        hangCancelBtn.setEnabled(false);
        chronometer.stop();
        endCallTriggerByMe = true;
        handler.sendEmptyMessage(MSG_CALL_END);
    }

    private void doClickHangAnswerBtn() {
        hangAnswerBtn.setEnabled(false);
        closeSpeakerOn();
        hangCancelLayout.setVisibility(View.GONE);
        hangMuteLayout.setVisibility(View.VISIBLE);
        handsFreeLayout.setVisibility(View.VISIBLE);
        handler.sendEmptyMessage(MSG_CALL_ANSWER);
    }

    private void initUserInfoView() {
        if (userEntity == null) {
            GlideUtils.setRoundImageView(this, null, R.drawable.default_avatar, destUserAvatar);
            destUserName.setText(username);
        } else {
            GlideUtils.setRoundImageView(this, userEntity.getAvatar(), R.drawable.default_avatar, destUserAvatar);
            destUserName.setText(AppUtils.getUserName(userEntity));
        }
    }

    private void doSyncFriend() {
        NetClient.getInstance()
                .getNetService(UserInterface.class)
                .getUser(AppUtils.getSignParams(username), username)
                .subscribe(new BaseObserver<BaseResponse<UserEntity>>() {
                    @Override
                    public void onSuccess(BaseResponse<UserEntity> response) {
                        userEntity = response.getInfo();
                        UserDao.getInstance().save(userEntity);
                        initUserInfoView();
                    }
                });
    }

    private void initOutgoingCallView() {

        voiceCallTip.setVisibility(View.VISIBLE);
        voiceCallTip.setText("正在等待对方接受邀请...");

        chronometer.setVisibility(View.GONE);
        hangCancelLayout.setVisibility(View.VISIBLE);

        hangUpLayout.setVisibility(View.GONE);
        hangMuteLayout.setVisibility(View.GONE);
        hangAnswerLayout.setVisibility(View.GONE);
        handsFreeLayout.setVisibility(View.GONE);

        initUserInfoView();
    }

    private void initComingCallView() {

        voiceCallTip.setVisibility(View.VISIBLE);
        voiceCallTip.setText("邀请你进行语音通话");

        chronometer.setVisibility(View.GONE);
        hangCancelLayout.setVisibility(View.GONE);

        hangUpLayout.setVisibility(View.VISIBLE);
        hangMuteLayout.setVisibility(View.GONE);
        hangAnswerLayout.setVisibility(View.VISIBLE);
        handsFreeLayout.setVisibility(View.GONE);
        hangUpTip.setText("拒绝");

        initUserInfoView();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onBackPressed() {
        callDruationText = chronometer.getText().toString();
    }

}
